package com.stillcoolme.basic.concurrent;

import com.stillcoolme.basic.utils.LocalDateTimeUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

// 可比较的任务包装器
class ComparableTask<T> implements Runnable, Comparable<ComparableTask<T>> {
    private final String taskName;
    private final int priority;

    public ComparableTask(String taskName, int priority) {
        this.taskName = taskName;
        this.priority = priority;
    }

    @Override
    public int compareTo(ComparableTask<T> other) {
        // 优先级数字越大，优先级越高（倒序排列）
        return Integer.compare(other.priority, this.priority);
    }

    @Override
    public void run() {
        System.out.println("执行线程池：" + taskName + " 执行时间：" + LocalDateTimeUtils.getCurrentDateTime());
    }
}

// 带优先级的任务
class PriorityTask implements Callable<String>, Comparable<PriorityTask> {
    private String taskName;
    private int priority;

    public PriorityTask(String taskName, int priority) {
        this.taskName = taskName;
        this.priority = priority;
    }

    public int getPriority() {
        return priority;
    }

    @Override
    public int compareTo(PriorityTask other) {
        // 优先级数字越大，优先级越高（倒序排列）
        return Integer.compare(other.priority, this.priority);
    }

    @Override
    public String call() throws Exception {
        Thread.sleep(2000);
        return "执行线程池：" + taskName + " 执行时间：" + LocalDateTimeUtils.getCurrentDateTime();
    }
}

// 优先级线程池
class PriorityThreadPool {
    private final ThreadPoolExecutor executor;

    public PriorityThreadPool(int corePoolSize, int maximumPoolSize) {
        // 使用 PriorityBlockingQueue 作为工作队列
        PriorityBlockingQueue<Runnable> queue = new PriorityBlockingQueue<>();

        this.executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                60L, TimeUnit.SECONDS,
                queue
        ) {
            @Override
            protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
                if (callable instanceof PriorityTask) {
                    PriorityTask priorityTask = (PriorityTask) callable;
                    return new ComparableFutureTask<>(callable, priorityTask.getPriority());
                }
                return super.newTaskFor(callable);
            }

            @Override
            protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
                if (runnable instanceof PriorityTask) {
                    PriorityTask priorityTask = (PriorityTask) runnable;
                    return new ComparableFutureTask<>(runnable, value, priorityTask.getPriority());
                }
                return super.newTaskFor(runnable, value);
            }
        };
    }

    // 自定义的可比较 FutureTask
    static class ComparableFutureTask<T> extends FutureTask<T> implements Comparable<ComparableFutureTask<T>> {
        private final int priority;

        public ComparableFutureTask(Callable<T> callable, int priority) {
            super(callable);
            this.priority = priority;
        }

        public ComparableFutureTask(Runnable runnable, T result, int priority) {
            super(runnable, result);
            this.priority = priority;
        }

        @Override
        public int compareTo(ComparableFutureTask<T> other) {
            // 优先级数字越大，优先级越高（倒序排列）
            return Integer.compare(other.priority, this.priority);
        }
    }

    public <T> Future<T> submit(Callable<T> task, int priority) {
        if (task instanceof PriorityTask) {
            PriorityTask priorityTask = (PriorityTask) task;
            return (Future<T>) executor.submit(priorityTask);
        }
//        else {
//            // 如果不是 PriorityTask，则使用默认优先级
//            ComparableFutureTask<T> comparableTask = new ComparableFutureTask<>(task, priority);
//            executor.execute(comparableTask);
//            return comparableTask;
//        }
        return null;
    }

    public void execute(Runnable runnable) {
        executor.execute(runnable);
    }

    public void shutdown() {
        executor.shutdown();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建优先级线程池
        PriorityThreadPool priorityThreadPool = new PriorityThreadPool(1, 1);

        List<Future<String>> futures = new ArrayList<>();

        futures.add(priorityThreadPool.submit(new PriorityTask("callable task1", 1), 1));
        futures.add(priorityThreadPool.submit(new PriorityTask("callable task11", 1), 1));
        futures.add(priorityThreadPool.submit(new PriorityTask("callable task2", 2), 2));

        priorityThreadPool.execute(new ComparableTask<>("runnable task1", 2));


        futures.add(priorityThreadPool.submit(new PriorityTask("callable task3", 3), 3));


        // 按提交顺序获取结果（注意：执行顺序可能不同）
        for (Future<String> future : futures) {
            String result = future.get(); // 阻塞直到任务完成
            System.out.println("收到结果: " + result);
        }

        priorityThreadPool.shutdown();
    }
}
